home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1997-2002 Alias|Wavefront,
- // a division of Silicon Graphics Limited.
- //
- // The information in this file is provided for the exclusive use of the
- // licensees of Alias|Wavefront. Such users have the right to use, modify,
- // and incorporate this code into other products for purposes authorized
- // by the Alias|Wavefront license agreement, without fee.
- //
- // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- //
- //
- // Assign File Textures to selected surface
- //
- proc int findShapeIndex(
- string $surfaceArray[],
- string $shapeName
-
- )
- //
- // Description:
- // For a given shape name find and returns its index in the
- // global active surface array
- //
- {
- int $shapeIdx;
- int $numbSurfaces = size( $surfaceArray );
- for ( $shapeIdx = 0; $shapeIdx < $numbSurfaces; $shapeIdx++ ) {
- string $longName = $surfaceArray[$shapeIdx];
- if ( $longName == $shapeName ) return $shapeIdx;
- }
- return -1;
- }
-
-
- proc string[] uniqueNodeList(
- string $nodes[]
- )
- //
- // Description:
- // Returns a unique list of nodes. Eliminate
- // all the dublicates.
- //
- {
- string $uniqueNodes[];
- int $nodeIndx = 0;
-
- for ( $node in $nodes ) {
- int $found = 0;
- for ($uNode in $uniqueNodes ) {
- if ( $node == $uNode ) {
- $found = 1;
- break;
- }
- }
-
- // Add it to the list.
- if ( $found == 0 ) {
- $uniqueNodes[$nodeIndx] = $node;
- $nodeIndx ++;
- }
- }
-
- return $uniqueNodes;
- }
-
-
- proc string[] findConnectedShapes(
- string $shadingEngine
- )
- //
- // Description:
- // Returns a list of shape names assigned to a given
- // shading engine node
- //
- {
- string $shadingPlug = $shadingEngine + ".dagSetMembers";
- string $tmpTransNodes[] = `listConnections -s true $shadingPlug`;
- string $transNodes[] = uniqueNodeList( $tmpTransNodes );
-
- string $shapeNodes[];
- int $idx = 0;
- for ( $trans in $transNodes ) {
- string $shapes[] = `listRelatives -shapes -pa $trans`;
- for ( $shape in $shapes ) {
- // Skip intermediate objects.
- int $intermediate = `getAttr ($shape + ".intermediateObject")`;
- if ( $intermediate )
- continue;
-
- // Add it to the list.
- $shapeNodes[$idx] = $shape;
- $idx ++;
- }
- }
- return $shapeNodes;
- }
-
-
- proc string getMaterialInfoNode(
- string $messagePlug
- )
- //
- // Description:
- // Returns a materialInfo connected through a given message plug
- //
- {
- string $connections[] = `listConnections $messagePlug`;
-
- for ( $item in $connections ) {
- if ( `objectType $item` == "materialInfo" )
- return $item;
- }
- return "";
- }
-
-
- proc string [] getShadingEngines(
- string $shape
- )
- //
- // Description:
- // Returns a unique list of shading engines for
- // a given shape.
- //
- {
- // Get all the shading engines.
- string $shadingEngs[] = `listConnections -d true -t "shadingEngine" $shape`;
-
- // Eliminte the dublicates.
- string $uniqueEngs[] = uniqueNodeList( $shadingEngs );
-
- return $uniqueEngs;
- }
-
-
- proc string createShadingEngine(
- string $shape
- )
- //
- // Description:
- // Creates a shading engine for a given shape. It is
- // assumed that the shape does not have a shading engine
- // assign to it. It returns the shading network
- // connections.
- //
- {
- string $group = `sets -renderable true -empty`;
- string $material = `shadingNode -asShader blinn`;
- string $shadingGroupName = "blinnSG" + $group;
- rename $group $shadingGroupName;
-
- surfaceShaderList -add $shadingGroupName $material;
- sets -e -forceElement $shadingGroupName $shape;
-
- // Return the shading engine connections.
- string $sEng[] = `listConnections -d true -t "shadingEngine" $shape`;
- return $sEng[0];
- }
-
-
- proc string createFileTextureNode( )
- //
- // Description:
- // Creates and returns a file texture node
- //
- {
- // Create a new texture and placement nodes.
- string $texture = `shadingNode -asTexture file`;
- string $place2d = `shadingNode -asUtility place2dTexture`;
-
- // Connect them together
- fileTexturePlacementConnect( $texture, $place2d );
-
- // we need to make the connection the the filter ourselves.
- connectAttr ($place2d + ".outUV") ($texture + ".uv");
- connectAttr ($place2d + ".outUvFilterSize") ($texture + ".uvFilterSize");
-
- // Return a newly created file texture node.
- return $texture;
- }
-
-
- proc int findShapeInSwitchNode(
- string $shape,
- string $switchNode
- )
- //
- // Description:
- // This function returns an index to the surface int
- // the switch node if the surface is already connected
- // to that switch node. Otherwise -1 is returned.
- //
- {
- string $nType = `nodeType $shape`;
-
- string $switchPlug = $switchNode + ".input";
- string $shapes[];
-
- if ( $nType == "mesh" ) {
- $shapes = `listConnections -sh 1 -type "mesh" $switchPlug`;
- } else if ( $nType == "nurbsSurface" ) {
- $shapes = `listConnections -sh 1 -type "nurbsSurface" $switchPlug`;
- } else if ( $nType == "subdiv" ) {
- $shapes = `listConnections -sh 1 -type "subdiv" $switchPlug`;
- } else {
- return -1;
- }
-
- int $idx;
- int $num = size( $shapes );
-
- for ($idx = 0; $idx < $num; $idx++ ) {
- if ( $shape == $shapes[$idx] )
- return $idx;
- }
- return -1;
- }
-
-
- proc string createSwitchNode(
- string $materialPlug
- )
- //
- // Description:
- // Create a switch node and connect it to the materialPlug
- //
- {
- string $switchNode;
-
- string $dataType = `getAttr -type $materialPlug`;
- if ( $dataType == "float3") {
- float $color[] = `getAttr $materialPlug`;
- $switchNode = `shadingNode -asUtility tripleShadingSwitch`;
- setAttr ($switchNode + ".default") $color[0] $color[1] $color[2];
- }
- else if ( $dataType == "float" ) {
- float $color = `getAttr $materialPlug`;
- $switchNode = `shadingNode -asUtility singleShadingSwitch`;
- setAttr ($switchNode + ".default") $color;
- }
-
- // Connect a newly created switch node to the material attribute.
- connectAttr -f ($switchNode + ".output") $materialPlug;
- return $switchNode;
- }
-
-
- proc createMultiFileTexture(
- string $switchShapes[],
- string $shadingEng,
- string $materialAttr
- )
- //
- // Description:
- // Creates a switch node and file textures for all shapes
- // int switchShapes array for the specified attributes and
- // connectes them properly.
- //
- {
- string $materialConn[] = `listConnections ($shadingEng + ".surfaceShader")`;
- string $material = $materialConn[0];
- string $materialPlug = $material + "." + $materialAttr;
- string $shaderSG[];
-
- if ( "normalCamera" == $materialAttr ) {
- string $textures[] = `listConnections $materialPlug`;
- string $bumpNode;
- if ( size( $textures ) > 0 ) {
- string $node = $textures[0];
- string $nType = `nodeType $node`;
-
- if ( $nType == "bump2d" ) {
- $bumpNode = $textures[0];
- } else {
- $bumpNode = `shadingNode -asUtility bump2d`;
- connectAttr -f ($bumpNode + ".outNormal") $materialPlug;
- }
- }
- else {
- // This is a bump map, so first create bump2d utility node
- // and connect it to the shader and the texture.
- $bumpNode = `shadingNode -asUtility bump2d`;
- connectAttr -f ($bumpNode + ".outNormal") $materialPlug;
- }
-
- // Reassign a material plug.
- $materialPlug = $bumpNode + ".bumpValue";
- }
- else if ( "displacement" == $materialAttr ) {
- if( $material == "lambert1" )
- {
- $shaderSG = `listConnections ($material + ".outColor")`;
- if( size( $shaderSG ) == 2 )
- {
- $materialPlug = ($shaderSG[1] + ".displacementShader");
- }
- else if( size( $shaderSG ) == 1 ) // new
- {
- $materialPlug = ($shaderSG[0] + ".displacementShader"); // new
- }
- else
- {
- $msg = "Cannot paint with " + $material + ", shader has multiple shader groups";
- warning $msg;
- }
- }
- else
- {
- $shaderSG = `listConnections ($material + ".outColor")`;
- // Note: If size of ShaderGroup is zero, new Shader Group is created
- if( size( $shaderSG ) == 1 )
- {
- $materialPlug = ($shaderSG[0] + ".displacementShader");
- }
- else if( size( $shaderSG ) > 1 )
- {
- // There are multiple shading group connected with same attribute.
- $msg = "Cannot paint with " + $material + ", shader has multiple shader groups";
- warning $msg;
- return;
- }
- }
- string $textures[] = `listConnections $materialPlug`;
-
- string $dispNode;
-
- if ( size( $textures ) > 0 ) {
- string $node = $textures[0];
- string $nType = `nodeType $node`;
-
- if ( $nType == "displacementShader" ) {
- $dispNode = $textures[0];
- } else {
- $dispNode = `shadingNode -asUtility displacementShader`;
- connectAttr -f ($dispNode + ".displacement") $materialPlug;
- }
- }
- else {
- // This is a displacement map, so first create displacement Shader utility node
- // and connect it to the shader and the texture.
- $dispNode = `shadingNode -asUtility displacementShader`;
- connectAttr -f ($dispNode + ".displacement") $materialPlug;
- }
-
- // Reassign a material plug.
- $materialPlug = $dispNode + ".displacement";
- }
-
- // Proceede only if either nothing is connected to the specified
- // material attribute or there is already a switch node.
- string $fileTextureName = "";
- string $existingTexture;
- string $textureAttr;
- string $switchNodeAttr;
- string $switchNode;
-
- string $textures[] = `listConnections -d off -s on $materialPlug`;
- if ( size( $textures ) > 0 ) {
- // There is already a node connected to this attribute
- // - check if this is a switch node and if not, return.
- string $node = $textures[0];
- string $nType = `nodeType $node`;
- if ( $nType == "file" ) {
- // Store the file texture name.
- string $fileTextureNamePlug = $textures[0] + ".fileTextureName";
- $fileTextureName = `getAttr $fileTextureNamePlug`;
-
- // Create a switch node and connected to the material node.
- $switchNode = createSwitchNode( $materialPlug );
- $existingTexture = $textures[0];
- }
- else {
- // We assume here that this is a switch node.
- $switchNode = $textures[0];
- }
- }
- else {
- $switchNode = createSwitchNode( $materialPlug );
- }
-
-
- // Get the names of the attributes for the switch node
- // and the file texture node.
- string $nType = `nodeType $switchNode`;
- if ( $nType == "tripleShadingSwitch" ) {
- $switchNodeAttr = "inTriple";
- $textureAttr = "outColor";
- }
- else if ( $nType == "singleShadingSwitch" ) {
- $switchNodeAttr = "inSingle";
- $textureAttr = "outAlpha";
- }
- else {
- // This is neither a switch nor a file texture node so return.
- warning("No switch node or file node connected to the paint attribute");
- return;
- }
-
- // Find out how many surfaces are connected to the switch node.
- string $tmpSwitchPlug = $switchNode + ".input";
- string $tmpSwitchConn[] = `listConnections $tmpSwitchPlug`;
- int $nextMultiIndex = size( $tmpSwitchConn )/2;
-
- // Connect the first surface to the existing texture.
- int $startIdx = 0;
- if ( $existingTexture != "" ) {
- string $shape = $switchShapes[0];
- string $shapePlug = $shape + ".instObjGroups[0]";
- int $srfIdx = findShapeInSwitchNode( $shape, $switchNode );
- if ( $srfIdx == -1 ) {
- string $switchNodeSurfacePlug =
- $switchNode+".input[" +$nextMultiIndex +"].inShape";
- string $switchNodeTexturePlug =
- $switchNode + ".input[" + $nextMultiIndex + "]." + $switchNodeAttr;
-
- string $texture = $existingTexture;
- string $texturePlug = $texture + "." + $textureAttr;
-
- // Connect shape and texture to the switch node.
- connectAttr -f $shapePlug $switchNodeSurfacePlug;
- connectAttr -f $texturePlug $switchNodeTexturePlug;
-
- // Increase the indices.
- $startIdx ++;
- $nextMultiIndex ++;
- }
- }
-
- // Now finally, create file textures for each of the
- // surfaces and assign pairs (shape+texture) to the
- // switch node.
- int $idx;
- int $switchShapeSize = size( $switchShapes );
- for ($idx = $startIdx; $idx<$switchShapeSize; $idx++ ) {
- // Get the shape and its plug.
- string $shape = $switchShapes[$idx];
- string $shapePlug = $shape + ".instObjGroups[0]";
-
- // We need to check if this surface is already
- // connected to the switch node.
- int $srfIdx = findShapeInSwitchNode( $shape, $switchNode );
- if ( $srfIdx != -1 )
- continue;
-
- // Get the switch node plugs.
- string $switchNodeSurfacePlug =
- $switchNode+".input[" + $nextMultiIndex +"].inShape";
- string $switchNodeTexturePlug =
- $switchNode + ".input[" + $nextMultiIndex + "]." + $switchNodeAttr;
-
- // Create a file texture node and get its plug.
- string $texture = createFileTextureNode();
- string $texturePlug = $texture + "." + $textureAttr;
-
- // If the file texture name is not empty, then set
- // the name of the file texture to that name.
- if ( $fileTextureName != "" ) {
- setAttr -type "string" ($texture + ".fileTextureName") $fileTextureName;
- }
-
- // Connect shape and texture to the switch node.
- connectAttr -f $shapePlug $switchNodeSurfacePlug;
- connectAttr -f $texturePlug $switchNodeTexturePlug;
-
- // Increase the indices.
- $nextMultiIndex ++;
- }
- }
-
-
- proc createSingleFileTexture(
- string $shape,
- string $shadingEng,
- string $materialAttr
- )
- //
- // Description:
- // Creates a file texture node for a given shape and connects it
- // to the specified attribute on the material (shader) node
- //
- {
- // Get the material node
- string $textureAttr = "";
- string $materialConn[] = `listConnections ($shadingEng + ".surfaceShader")`;
- string $material = $materialConn[0];
-
- string $msg = $shadingEng + " cannot paint the current attribute because there is a non-file texture connected.";
-
- // Proceede only if nothing is no file texture node connected.
-
- string $textures[];
- string $dispShadingGroupShader;
- string $shaderSG[];
-
- if( $materialAttr == "displacement" )
- {
- if( $material == "lambert1" )
- {
- $shaderSG = `listConnections ($material + ".outColor")`;
- if( size( $shaderSG ) == 2 )
- {
- $dispShadingGroupShader = ($shaderSG[1] + ".displacementShader");
- }
- else if( size( $shaderSG ) == 1 )
- {
- $dispShadingGroupShader = ($shaderSG[0] + ".displacementShader");
- }
- else
- {
- $msg = " Cannot paint with " + $material + ", shader has multiple shader groups";
- warning $msg;
- return;
- }
- }
- else
- {
- $shaderSG = `listConnections ($material + ".outColor")`;
- // Note: If size of ShaderGroup is zero, new Shader Group is created
- if( size( $shaderSG ) == 1 )
- {
- $dispShadingGroupShader = ($shaderSG[0] + ".displacementShader");
- }
- else if( size( $shaderSG ) > 1 )
- {
- // There are multiple shading group connected with same attribute.
- $msg = " Cannot paint with " + $material + ", shader has multiple shader groups";
- warning $msg;
- return;
- }
- }
- $textures = `listConnections ($dispShadingGroupShader)`;
- }
- else
- {
- $textures = `listConnections ($material + "." + $materialAttr)`;
- }
- if ( "normalCamera" == $materialAttr ) {
- string $bumpNode = "";
- if ( size( $textures ) > 0 ) {
- string $nType = `nodeType $textures[0]`;
- if ( $nType == "bump2d" ) {
- // There is already a bymp node connected.
- $bumpNode = $textures[0];
-
- // Check if there is also a file texture node there.
- string $bumpConns[] = `listConnections ($bumpNode + ".bumpValue")`;
- if ( size( $bumpConns ) > 0 ) {
- $nType = `nodeType $bumpConns[0]`;
- if ( $nType != "file" ) {
- // Print a warning if there is anything else connected.
- warning $msg;
- }
- return;
- }
- }
- else {
- // There only node allowed here is bump node.
- $msg = $shadingEng + " cannot paint the current attribute because there is a no bump node connected.";
- warning $msg;
- return;
- }
- }
-
- // If there is not bump node, create it and
- // connect it to the shader.
- if ( $bumpNode == "" ) {
- $bumpNode = `shadingNode -asUtility bump2d`;
- connectAttr ($bumpNode + ".outNormal") ($material + "." + $materialAttr);
- }
-
- // Finally, create a file texture node and connect it to the bump node.
- string $texture = createFileTextureNode();
- connectAttr ($texture + ".outAlpha") ($bumpNode + ".bumpValue");
- }
- else if ( "displacement" == $materialAttr ) {
- string $dispNode = "";
- if ( size( $textures ) > 0 ) {
- string $nType = `nodeType $textures[0]`;
-
- if ( $nType == "displacementShader" ) {
- // There is already a disp node connected.
- $dispNode = $textures[0];
-
- // Check if there is also a file texture node there.
- string $dispConns[] = `listConnections ($dispNode + ".displacement")`;
- if ( size( $dispConns ) > 0 ) {
- $nType = `nodeType $dispConns[0]`;
- if ( $nType != "file" ) {
- // Print a warning if there is anything else connected.
- warning $msg;
- }
- return;
- }
- }
- else {
- // There only node allowed here is disp node.
- $msg = $shadingEng + " cannot paint the current attribute because there is a no displacement node connected.";
- warning $msg;
- return;
- }
- }
-
- // If there is not disp node, create it and
- // connect it to the shader.
- if ( $dispNode == "" ) {
- $dispNode = `shadingNode -asUtility displacementShader`;
- connectAttr ($dispNode + ".displacement") ($dispShadingGroupShader);
- }
-
- // Finally, create a file texture node and connect it to the bump node.
- string $texture = createFileTextureNode();
- connectAttr ($texture + ".outAlpha") ($dispNode + ".displacement");
- }
- else {
-
- // Check if there is already a node connected to the attribute.
- if ( size( $textures ) > 0 ) {
- string $nType = `nodeType $textures[0]`;
- if ( $nType != "file" ) {
- // Print a warning if there is no file texture node connected.
- warning $msg;
- }
- return;
- }
-
- // Create a file texture node.
- string $texture = createFileTextureNode();
-
- // Get the texture attribute name (plug).
- string $materialPlug = $material + "." + $materialAttr;
- string $dataType = `getAttr -type $materialPlug`;
-
- if ( $dataType == "float3") {
- $textureAttr = "outColor";
- } else if ( $dataType == "float" ) {
- $textureAttr = "outAlpha";
- }
-
- // Make the specified by the user connection.
- connectAttr ($texture + "." + $textureAttr) ($material + "." + $materialAttr);
- }
- }
-
-
- global proc art3dPaintAssignFileTextures(
- string $materialAttr
- )
- //
- // Description:
- // Traverse the selection list, and if necessary create file textures
- // for all surfaces which are on the list. The user specifies a material
- // node attribute to which the connection with the file texture needs to
- // exist. If the file texture on this attribute already exists, nothing
- // is done, otherwise a file texture node with a dummy texture is created
- // and connected to the shape node. Paint tool has to allocate a physical
- // image for the file texture and change the name into a proper one.
- //
- {
- // Get the active surfaces from the paint color context
- // and initialize the global tables.
- string $activeSrfArray[];
- string $srfNames = eval("art3dPaintCtx -q -shapenames `currentCtx`");
- if ( size( $srfNames ) == 0 )
- return;
-
- int $numbActiveSrf = `tokenize $srfNames $activeSrfArray`;
- int $surfaceHasTexture[];
- for ( $idx = 0; $idx < $numbActiveSrf; $idx++ ) {
- $surfaceHasTexture[$idx] = 0;
- }
-
- // Now generate file textures.
- for ( $idx = 0; $idx < $numbActiveSrf; $idx++ ) {
-
- // Get the surface.
- string $shape = $activeSrfArray[$idx];
- if ( $shape == "" ) continue;
- if ( $surfaceHasTexture[$idx] == 1 ) continue;
-
- // Find the shading engine ( if it does not exist, create one ).
- string $sEng[] = getShadingEngines( $shape );
- int $sEngSize = size( $sEng );
-
- if ( $sEngSize == 0 ) {
- $sEng[0] = createShadingEngine( $shape );
- $sEngSize = 1;
- }
-
- for ( $sIdx = 0; $sIdx < $sEngSize; $sIdx++ ) {
- // Get the shading engine.
- string $shadingEng = $sEng[$sIdx];
-
- // Find out how many surfaces are connected to this shading engine
- // and if there is more than one, then we need a switch node.
- string $tmpShapes[] = findConnectedShapes( $shadingEng );
- int $tmpNumShapes = size( $tmpShapes );
-
- if ( $tmpNumShapes > 1 ) {
- // Eliminate all the shapes which are not selected.
- string $switchShapes[];
- int $ii = 0;
- for ( $shapeName in $tmpShapes ) {
- int $shapeIdx = findShapeIndex( $activeSrfArray, $shapeName );
- if ( $shapeIdx == -1 ) continue;
-
- // Add surface to the list.
- $switchShapes[$ii] = $shapeName;
-
- // Mark the surface so we don't try to create
- // a texture node again for it.
- $surfaceHasTexture[$shapeIdx] = 1;
- $ii ++;
- }
-
- // Create a switch node.
- createMultiFileTexture( $switchShapes, $shadingEng, $materialAttr );
- }
- else {
- // Create a single texture.
- createSingleFileTexture( $shape, $shadingEng, $materialAttr );
-
- // Mark the surface.
- $surfaceHasTexture[$idx] = 1;
- }
- }
- }
- }